home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1998 April: Mac OS SDK / Dev.CD Apr 98 SDK1.toast / Development Kits (Disc 1) / Macintosh Drag and Drop / Demo Applications / Dragster / DragText Sources / document.c < prev    next >
Encoding:
C/C++ Source or Header  |  1995-01-03  |  11.2 KB  |  486 lines  |  [TEXT/KAHL]

  1. /*
  2.  *
  3.  *        document.c
  4.  *
  5.  *        Document handling routines.
  6.  *        
  7.  *
  8.  *        Author:        Rob Johnston
  9.  *        Date:        Monday, February 10, 1992
  10.  *
  11.  *        12/30/94    JML        Code now compiles with Universal interfaces.
  12.  *
  13.  *        Copyright © 1992 Apple Computer, Inc.
  14.  *
  15.  */
  16.  
  17. #include <ToolUtils.h>
  18. #include <Dialogs.h>
  19. #include <Drag.h>
  20. #include "globals.h"
  21. #include "prototypes.h"
  22. #include "DTResources.h"
  23.  
  24. extern pascal OSErr MyTrackingHandler(short message, WindowPtr theWindow,
  25.                                          void *handlerRefCon, DragReference theDrag);
  26.  
  27. extern pascal OSErr MyReceiveDropHandler(WindowPtr theWindow, void *handlerRefCon,
  28.                                          DragReference theDrag);
  29.  
  30.  
  31. /*
  32.  *    AdjustDocumentView scrolls the document image by the appropriate amount
  33.  *    if the scroll bar value has changed.
  34.  */
  35.  
  36. void AdjustDocumentView(Document *theDocument)
  37.  
  38. {    short        delta, docTop, docTopLimit;
  39.  
  40.     delta = (theDocument->vScrollPos - GetCtlValue(theDocument->vScroll)) *
  41.                 ScrollResolution;
  42.  
  43.     if (delta) {
  44.         if (delta > 0) {
  45.             docTop = (**(theDocument->theTE)).destRect.top;
  46.             docTopLimit = (**(theDocument->theTE)).viewRect.top + TopMargin;
  47.             if (docTop + delta > docTopLimit) {
  48.                 delta = docTopLimit - docTop;
  49.             }
  50.         }
  51.         TEScroll(0, delta, theDocument->theTE);
  52.         theDocument->vScrollPos = GetCtlValue(theDocument->vScroll);
  53.     }
  54. }
  55.  
  56.  
  57. /*
  58.  *    AdjustScrollBar calculates the current position and maximum value of the
  59.  *    document's scroll bar given the current viewing position and document
  60.  *    text. This routine is called whenever the text is changed or the view
  61.  *    is auto-scrolled.
  62.  */
  63.  
  64. void AdjustScrollBar(Document *theDocument)
  65.  
  66. {    short        docTop, docBottom, viewTop, viewBottom;
  67.     short        offTop, offBottom;
  68.     RgnHandle    viewRgn;
  69.  
  70.     docTop = (**(theDocument->theTE)).destRect.top;
  71.     docBottom = docTop + TEGetHeight(32767, 0, theDocument->theTE);
  72.     viewTop = (**(theDocument->theTE)).viewRect.top;
  73.     viewBottom = (**(theDocument->theTE)).viewRect.bottom;
  74.  
  75.     offTop = ((viewTop - (docTop - TopMargin)) + ScrollResolution - 1) / ScrollResolution;
  76.     offBottom = (((docBottom + BottomMargin) - viewBottom) + ScrollResolution - 1) / ScrollResolution;
  77.     if (offTop < 0)
  78.         offTop = 0;
  79.     if (offBottom < 0)
  80.         offBottom = 0;
  81.  
  82.     theDocument->vScrollPos = offTop;
  83.  
  84.     SetCtlMax(theDocument->vScroll, offTop + offBottom);
  85.     SetCtlValue(theDocument->vScroll, offTop);
  86.  
  87.     viewRgn = NewRgn();
  88.     RectRgn(viewRgn, &(**(theDocument->theTE)).viewRect);
  89.     SectRgn(viewRgn, theDocument->hiliteRgn, theDocument->hiliteRgn);
  90.     DisposeRgn(viewRgn);
  91. }
  92.  
  93.  
  94. /*
  95.  *    This routine computes the size and location of the window's scroll bars
  96.  *    and the TextEdit field given the current size of the window. This routine
  97.  *    is called to initialize these components of the window and to update
  98.  *    the position of these components when the window is resized.
  99.  */
  100.  
  101. void PositionDocumentParts(Document *theDocument)
  102.  
  103. {    Rect        theRect;
  104.  
  105.     theRect = theDocument->theWindow->portRect;
  106.     theRect.left = theRect.right - 15;
  107.     theRect.right  += 1;
  108.     theRect.bottom -= 14;
  109.     theRect.top    -= 1;
  110.     (**(theDocument->vScroll)).contrlRect = theRect;
  111.  
  112.     theRect = theDocument->theWindow->portRect;
  113.     theRect.top = theRect.bottom - 15;
  114.     theRect.bottom += 1;
  115.     theRect.right  -= 14;
  116.     theRect.left   -= 1;
  117.     (**(theDocument->hScroll)).contrlRect = theRect;
  118.  
  119.     theRect = theDocument->theWindow->portRect;
  120.     theRect.right  -= 15;
  121.     theRect.bottom -= 15;
  122.     (**(theDocument->theTE)).viewRect = theRect;
  123.     (**(theDocument->theTE)).destRect.right = theRect.right - RightMargin;
  124.     TECalText(theDocument->theTE);
  125. }
  126.  
  127.  
  128. /*
  129.  *    NewDocument is called when a new document window is needed. Creation of
  130.  *    document data structures is handled here.
  131.  */
  132.  
  133. Document *NewDocument(void)
  134.  
  135. {    Document        *theDocument;
  136.     WindowPtr        theWindow;
  137.     Rect            theRect = { 0, 0, 16, 16 };
  138.     TextStyle        theStyle;
  139.     TEStyleHandle    theStyleHandle;
  140.     Point            thePoint;
  141. //    DragHandler        theHandler;
  142.     OSErr            result;
  143.  
  144.     if (gDocumentCount == MaxDocumentCount)
  145.         return((Document *) 0L);
  146.  
  147.     theDocument = gDocumentList[gDocumentCount++] =
  148.                             (Document *) NewPtr(sizeof(Document));
  149.  
  150.     theDocument->theWindow = theWindow = 
  151.                     GetNewWindow(WindowTemplateID, 0L, (WindowPtr) -1L);
  152.     ((WindowPeek) theWindow)->refCon = (long) theDocument;
  153.     SetPort(theWindow);
  154.  
  155.     thePoint = *((Point *) (&theWindow->portRect.top));
  156.     LocalToGlobal(&thePoint);
  157.     if (thePoint.h < 10) {
  158.         MoveWindow(theWindow, InitialH, InitialV, false);
  159.     }
  160.  
  161.     theDocument->vScroll = NewControl(theWindow, &theRect, "\p", true, 0, 0, 0,
  162.                                       scrollBarProc, (long) theDocument);
  163.     theDocument->hScroll = NewControl(theWindow, &theRect, "\p", true, 0, 0, 0,
  164.                                       scrollBarProc, (long) theDocument);
  165.  
  166.     theDocument->theTE = TEStylNew(&theRect, &theRect);
  167.     (**(theDocument->theTE)).destRect.top    = TopMargin;
  168.     (**(theDocument->theTE)).destRect.left   = LeftMargin;
  169.     (**(theDocument->theTE)).destRect.bottom = 32767;
  170.  
  171.     TEAutoView(true, theDocument->theTE);
  172.  
  173.     TEFeatureFlag(teFOutlineHilite, TEBitSet, theDocument->theTE);
  174.  
  175.     theDocument->hiliteRgn = NewRgn();
  176.     theStyleHandle = GetStylHandle(theDocument->theTE);
  177.     (**theStyleHandle).teRefCon = (long) theDocument;
  178.  
  179.     theStyle.tsFont = 21;
  180.     theStyle.tsSize = 12;
  181.     TESetStyle(doFont + doSize, &theStyle, false, theDocument->theTE);
  182.  
  183.     theDocument->vScrollPos = 0;
  184.     theDocument->fRefNum = 0;
  185.     theDocument->dirty = false;
  186.     theDocument->undoDragText = 0L;
  187.  
  188.     PositionDocumentParts(theDocument);
  189.  
  190.     InstallTrackingHandler(MyTrackingHandler, theWindow, (void *) theDocument);
  191.     InstallReceiveHandler(MyReceiveDropHandler, theWindow, (void *) theDocument);
  192.  
  193.     return(theDocument);
  194. }
  195.  
  196.  
  197. /*
  198.  *    CloseDocument is called when a document window is being closed. Storage
  199.  *    of the document file and disposal of document data structures is handled
  200.  *    here.
  201.  */
  202.  
  203. void CloseDocument(Document *theDocument)
  204.  
  205. {    short            result, index, response;
  206.     Str255            theName, theVerb;
  207.  
  208.     index = 0;
  209.     while ((gDocumentList[index] != theDocument) && (index < MaxDocumentCount))
  210.         index++;
  211.  
  212.     if (gDocumentList[index] == theDocument) {
  213.  
  214.         if (theDocument->dirty) {
  215.             GetWTitle(theDocument->theWindow, theName);
  216.             GetIndString(theVerb, FileStringsID, (gQuitting) ? slQuittingIndex : slClosingIndex);
  217.             ParamText(theName, theVerb, "\p", "\p");
  218.             SetCursor(&qd.arrow);
  219.             response = Alert(idSaveChangesALRT, 0L);
  220.  
  221.             if (response == 1) {            /* Save */
  222.                 if (! DoSaveDocument(theDocument)) {
  223.                     gQuitting = false;
  224.                     return;
  225.                 }
  226.             } else if (response == 3) {        /* Don't Save */
  227.                 ;
  228.             } else {                        /* Cancel */
  229.                 gQuitting = false;
  230.                 return;
  231.             }
  232.  
  233.         }
  234.  
  235.         if (theDocument->fRefNum) {
  236.             FSClose(theDocument->fRefNum);
  237.         }
  238.  
  239.         RemoveTrackingHandler(MyTrackingHandler, theDocument->theWindow);
  240.         RemoveReceiveHandler(MyReceiveDropHandler, theDocument->theWindow);
  241.  
  242.         DisposeRgn(theDocument->hiliteRgn);
  243.         TEDispose(theDocument->theTE);
  244.         DisposeWindow(theDocument->theWindow);
  245.  
  246.         if (theDocument->undoDragText) {
  247.             DisposHandle(theDocument->undoDragText);
  248.             theDocument->undoDragText = 0L;
  249.         }
  250.  
  251.         while (index < MaxDocumentCount) {
  252.             gDocumentList[index] = gDocumentList[index + 1];
  253.             index++;
  254.         }
  255.  
  256.         DisposPtr((Ptr) theDocument);
  257.         gDocumentCount--;
  258.     }
  259. }
  260.  
  261.  
  262. /*
  263.  *    DoActivateDocument is called when an event is received that reports that
  264.  *    a document window is being either activated or deactivated.
  265.  */
  266.  
  267. short DoActivateDocument(Document *theDocument, short activate)
  268.  
  269. {    WindowPtr        theWindow;
  270.  
  271.     if (theDocument) {
  272.         if (activate) {
  273.             TEActivate(theDocument->theTE);
  274.             HiliteControl(theDocument->vScroll, 0);
  275.             HiliteControl(theDocument->hScroll, 0);
  276.  
  277.             TEGetHiliteRgn(theDocument->hiliteRgn, theDocument->theTE);
  278.  
  279.         } else {
  280.             TEDeactivate(theDocument->theTE);
  281.             HiliteControl(theDocument->vScroll, 255);
  282.             HiliteControl(theDocument->hScroll, 255);
  283.         }
  284.     }
  285. }
  286.  
  287.  
  288.  
  289. /*
  290.  *    Closes all document windows.
  291.  */
  292.  
  293. void CloseAllDocuments()
  294.  
  295. {
  296.     while (gDocumentCount) {
  297.         CloseDocument(gDocumentList[0]);
  298.     }
  299. }
  300.  
  301.  
  302. /*
  303.  *    If the given WindowPtr is a pointer to a document window, this function
  304.  *    returns a pointer to a document data structure. If the window is not
  305.  *    a document window, the function returns NULL.
  306.  */
  307.  
  308. Document *IsDocumentWindow(WindowPtr theWindow)
  309.  
  310. {    short        index = 0;
  311.     Document    *theDocument;
  312.  
  313.     theDocument = (Document *) (((WindowPeek) theWindow)->refCon);
  314.  
  315.     while ((gDocumentList[index] != theDocument) && (index < gDocumentCount))
  316.         index++;
  317.  
  318.     if (gDocumentList[index] == theDocument)
  319.         return(theDocument);
  320.     else
  321.         return((Document *) 0L);
  322. }
  323.  
  324.  
  325. /*
  326.  *    DoFontSelection is called when the user chooses a font from the font menu.
  327.  */
  328.  
  329. short DoFontSelection(short fontNumber)
  330.  
  331. {    TextStyle        theStyle;
  332.     WindowPtr        theWindow;
  333.     Document        *theDocument;
  334.  
  335.     if (theWindow = FrontWindow()) {
  336.         if (theDocument = IsDocumentWindow(theWindow)) {
  337.             theStyle.tsFont = fontNumber;
  338.             TESetStyle(doFont, &theStyle, true, theDocument->theTE);
  339.         }
  340.     }
  341. }
  342.  
  343.  
  344. /*
  345.  *    DoSizeSelection is called when the user selects a font size from the
  346.  *    Size menu.
  347.  */
  348.  
  349. short DoSizeSelection(short fontSize)
  350.  
  351. {    TextStyle        theStyle;
  352.     WindowPtr        theWindow;
  353.     Document        *theDocument;
  354.  
  355.     if (theWindow = FrontWindow()) {
  356.         if (theDocument = IsDocumentWindow(theWindow)) {
  357.             theStyle.tsSize = fontSize;
  358.             TESetStyle(doSize, &theStyle, true, theDocument->theTE);
  359.         }
  360.     }
  361. }
  362.  
  363.  
  364. /*
  365.  *    DoStyleSelection is called when the user chooses a style from the
  366.  *    Style menu.
  367.  */
  368.  
  369. short DoStyleSelection(short styleItem)
  370.  
  371. {    TextStyle        theStyle;
  372.     WindowPtr        theWindow;
  373.     Document        *theDocument;
  374.  
  375.     if (theWindow = FrontWindow()) {
  376.         if (theDocument = IsDocumentWindow(theWindow)) {
  377.             theStyle.tsFace = 0;
  378.             if (styleItem > 1) {
  379.                 BitSet(&theStyle.tsFace, 9 - styleItem);
  380.                 TESetStyle(doFace + doToggle, &theStyle, true, theDocument->theTE);
  381.             } else {
  382.                 TESetStyle(doFace, &theStyle, true, theDocument->theTE);
  383.             }
  384.         }
  385.     }
  386. }
  387.  
  388.  
  389. /*
  390.  *    DoSelectAllDocument is called when the Select All menu command is chosen.
  391.  */
  392.  
  393. short DoSelectAllDocument(Document *theDocument)
  394.  
  395. {
  396.     if (theDocument) {
  397.         TESetSelect(0, 32767, theDocument->theTE);
  398.     }
  399. }
  400.  
  401.  
  402. /*
  403.  *    DisableUndoDrag is called when the last drag can no longer be undone.
  404.  *    This routine disposes of undo text allocations.
  405.  */
  406.  
  407. short DisableUndoDrag()
  408.  
  409. {    short            index;
  410.     Document        *theDoc;
  411.  
  412.     gCanUndoDrag = slCantUndo;
  413.  
  414.     index = gDocumentCount;
  415.     while (index--) {
  416.         theDoc = gDocumentList[index];
  417.         if (theDoc->undoDragText) {
  418.             DisposHandle(theDoc->undoDragText);
  419.             theDoc->undoDragText = 0L;
  420.         }
  421.     }
  422. }
  423.  
  424.  
  425. /*
  426.  *    DoUndoDrag is called when the user chooses Undo Drag.
  427.  */
  428.  
  429. short DoUndoDrag()
  430.  
  431. {    short            index, selStart, selEnd;
  432.     Document        *theDoc;
  433.     Handle            theText;
  434.     long            theSize;
  435.     WindowPtr        theWindow;
  436.     Rect            theRect;
  437.  
  438.     if (gCanUndoDrag != slCantUndo) {
  439.  
  440.         theWindow = 0L;
  441.         index = gDocumentCount;
  442.         while (index--) {
  443.             theDoc = gDocumentList[index];
  444.             SetPort(theDoc->theWindow);
  445.     
  446.             if (theText = theDoc->undoDragText) {
  447.  
  448.                 theDoc->undoDragText = (**theDoc->theTE).hText;
  449.                 (**theDoc->theTE).hText = theText;
  450.  
  451.                 TECalText(theDoc->theTE);
  452.  
  453.                 selStart = theDoc->undoSelStart;
  454.                 selEnd   = theDoc->undoSelEnd;
  455.                 TESetSelect(selStart, selEnd, theDoc->theTE);
  456.                 theDoc->undoSelStart = theDoc->lastSelStart;
  457.                 theDoc->undoSelEnd   = theDoc->lastSelEnd;
  458.                 theDoc->lastSelStart = selStart;
  459.                 theDoc->lastSelEnd   = selEnd;
  460.  
  461.                 theRect = theDoc->theWindow->portRect;
  462.                 theRect.right  -= 15;
  463.                 theRect.bottom -= 15;
  464.                 EraseRect(&theRect);
  465.                 TEUpdate(&theRect, theDoc->theTE);
  466.             }
  467.         }
  468.  
  469.         if (gCanUndoDrag == slUndoDrag)
  470.             gCanUndoDrag = slRedoDrag;
  471.         else
  472.             gCanUndoDrag = slUndoDrag;
  473.  
  474.         theWindow = gUndoFrontmost;
  475.         gUndoFrontmost = gLastFrontmost;
  476.         gLastFrontmost = theWindow;
  477.     }
  478. }
  479.  
  480.  
  481.  
  482.  
  483.  
  484.  
  485.  
  486.